講polymorphism多型,大多數是從「拆字算命」(還好不用紫微斗數)起頭。吾從眾:
polymorphism
一詞,是poly
和morphism
兩字的組合(註1)。
poly
字源來自希臘的polýs
,意思是many
「多」。morph
亦沿自希臘的morphḗ
,意思是shape
「形狀、形態」。many shapes
,就是多種形狀或多個型態之意。中文通常譯為「多型」或「多形」,多型較普及,所以下面都講「多型」。至於具體意義,容後詳述。Parent obj = new Child();
。這時的Parent可以說是「形式類別」,Child則是「實際類別」。doSomething()
時(當然這個方法在形式類別和實際類別都要存在才行),實際執行的會是「實際類別」也就是子類別的doSomething(),而不是「形式類別」(父類別)的doSomething()。using System;
namespace MyApplication
{
class Tree // Base class (parent)
{
public virtual void bloom() // 要加virtual
{
Console.WriteLine("I am a virtual Tree, so I don't know whether I will bloom.");
}
}
class Hardwood : Tree // Derived class (child)
{
public override void bloom() // 要加override
{
Console.WriteLine("I am a Hardwood, so I bloom every year.");
}
public void doExtraWorks() // 子類別擴充的方法
{
Console.WriteLine("A Hardwood is doing extra works.");
}
}
class Conifer : Tree // Derived class (child)
{
public override void bloom() // 要加override
{
Console.WriteLine("I am a Conifer, so I DON'T bloom.");
}
public void doExtraWorks() // 子類別擴充的方法
{
Console.WriteLine("A Conifer is doing extra works.");
}
}
class VenusianTree : Tree // 金星上的樹
{
public override void bloom() // 要加override
{
Console.WriteLine("Being a Venusian tree, I bloom once every 100 years.");
}
public void doExtraWorks() // 子類別擴充的方法
{
Console.WriteLine("A VenusianTree is doing extra works.");
}
}
class MartianTree : Tree // 火星上的樹
{
public override void bloom() // 要加override
{
Console.WriteLine("Being a Martian tree, I don't have the concept of blooming.");
}
public void doExtraWorks() // 子類別擴充的方法
{
Console.WriteLine("A MartianTree is doing extra works.");
}
}
class SaturnianTree : Tree // 土星上的樹
{
public override void bloom() // 要加override
{
Console.WriteLine("Being a Saturnian tree, I don't have any shape(ghostlymorphism).");
}
public void doExtraWorks() // 子類別擴充的方法
{
Console.WriteLine("A SaturnianTree is doing extra works.");
}
}
class Program
{
static void Main(string[] args)
{
Tree tree = new Tree(); // Create a Tree object
Tree hardwood = new Hardwood(); // Create a Hardwood object
Tree conifer = new Conifer(); // Create a Conifer object
Tree venusianTree = new VenusianTree(); // Create a VenusianTree object
Tree martianTree = new MartianTree(); // Create a MartianTree object
Tree saturnianTree = new SaturnianTree(); // Create a SaturnianTree object
tree.bloom();
Tree[] trees = {hardwood, conifer, venusianTree, martianTree, saturnianTree};
Random rnd = new Random();
int thisTree = rnd.Next(0, 5);
trees[thisTree].bloom();
// 由於Tree類別並無doExtraWorks(),下列這行執行時會報錯。
// trees[thisTree].doExtraWorks();
}
}
}
saturnianTree.bloom();
,也是在執行時期才決定呼叫父子兩類別中的哪一個bloom()。筆者使用隨機寫法,只是故意強調而已。Tree hardwood = new Hardwood();
這個寫法。hardwood物件宣告為Tree
型別,實際new的卻是Tree的子類別Hardwood
。Tree
,所以它只能使用Tree所提供的屬性和方法。下面的寫法是錯的:
class Program
{
static void Main(string[] args)
{
Tree tree = new Tree(); // Create a Tree object
Tree hardwood = new Hardwood(); // Create a Hardwood object
Tree conifer = new Conifer(); // Create a Conifer object
Tree venusianTreeTree = new VenusianTree(); // Create a VenusianTree object
Tree martianTree = new MartianTree(); // Create a MartianTree object
Tree saturnianTree = new SaturnianTree(); // Create a SaturnianTree object
tree.bloom();
Tree[] trees = {hardwood, conifer, venusianTreeTree, martianTree, saturnianTree};
Random rnd = new Random();
int thisTree = rnd.Next(0, 5);
// 由於Tree類別並無doExtraWorks(),下列這行執行時會報錯。
trees[thisTree].doExtraWorks();
}
}
doExtraWorks()
時出錯了,原因是父類別Tree
並未定義這個方法:今天算是對多型的簡單介紹,明天有無辦法講得更加透徹,得看筆者的時間和精力了。
註1: 開個玩笑:
POLY_MORPHISM
PolyMorphism
polyMorphism
poly_morphism
註2: Overloading可以細分為function overloading和operator overloading兩種。
+
運算子,可以用於int / float的相加,也可以用於字串的「連接」,同一+
號,可用於不同型別資料,這就是operator overloading。不過這是Python內建的overloading,使用者無法自訂。